package net.studou.dao;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import net.studou.po.IoLog;
import net.studou.po.Page;
import net.studou.po.User;
import net.studou.tools.Utils;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.stereotype.Component;

@Component("ioLogDao")
public class IoLogDao extends CommonDao {

	public IoLogDao() {
		super.clazz = IoLog.class;
	}

	 @SuppressWarnings("unchecked")
	    public List<IoLog> findIO(final IoLog ioLog, final User user, final Page page) {
	        List<IoLog> ioLogs = null;
	        try {
	            ioLogs = getHibernateTemplate().executeFind(new HibernateCallback() {
	                public Object doInHibernate(Session session) throws HibernateException, SQLException {
	                    Integer ioType = ioLog.getIoType();
	                    Integer ioStatus = ioLog.getStatus();
	                    Date begin = ioLog.getBegin();
	                    Date end = ioLog.getEnd();
	                    if (ioStatus == null || ioStatus == 0) {
	                        String sql1 = "select * from iolog as io where io.status = 1 and io.uId = " + user.getUserId();
	                        String sql2 = "select * from iolog as iolog where iolog.status != 1 and iolog.uId = " + user.getUserId();
	                        if (ioType != null && ioType != 0) {
	                            sql1 = sql1 + " and io.ioType = " + ioType;
	                            sql2 = sql2 + " and iolog.ioType = " + ioType;
	                        }
	                        if (begin != null) {
	                            sql1 = sql1 + " and io.createTime > '" + Utils.NORMAL.format(begin) + "'";
	                            sql2 = sql2 + " and iolog.createTime > '" + Utils.NORMAL.format(begin) + "'";
	                        }
	                        if (end != null) {
	                            sql1 = sql1 + " and io.createTime < '" + Utils.NORMAL.format(end) + "'";
	                            sql2 = sql2 + " and iolog.createTime < '" + Utils.NORMAL.format(end) + "'";
	                        }
	                        sql1 = sql1 + " order by io.createTime desc";
	                        sql2 = sql2 + " order by iolog.createTime desc";

	                        String sql = "select * from (" + sql1 + ") as log1" + " union all" + " select * from (" + sql2 + ") as log2";
	                        String countSql = "select count(*) as cnt from (" + sql + ") as log3";

	                        SQLQuery query = session.createSQLQuery(countSql);
	                        query.addScalar("cnt", new org.hibernate.type.IntegerType());
	                        List<Integer> cnts = query.list();
	                        page.setSum((long) (cnts.get(0).intValue()));
	                        Long count = page.getCountPage3();
	                        final long from = count < page.getCurPage() ? count : page.getCurPage();
	                        page.setCurPage(from);

	                        query = session.createSQLQuery(sql);
	                        query.setFirstResult((int) ((from - 1) * page.getPageSize3()));
	                        query.setMaxResults(page.getPageSize3());
	                        query.addScalar("ioId", new org.hibernate.type.IntegerType());
	                        query.addScalar("uId", new org.hibernate.type.IntegerType());
	                        query.addScalar("ioNo", new org.hibernate.type.StringType());
	                        query.addScalar("ioType", new org.hibernate.type.IntegerType());
	                        query.addScalar("money", new org.hibernate.type.DoubleType());
	                        query.addScalar("ago", new org.hibernate.type.DoubleType());
	                        query.addScalar("after", new org.hibernate.type.DoubleType());
	                        query.addScalar("createTime", new org.hibernate.type.TimestampType());
	                        query.addScalar("status", new org.hibernate.type.IntegerType());
	                        query.addScalar("details", new org.hibernate.type.StringType());
	                        query.addScalar("tbUrl", new org.hibernate.type.StringType());
	                        query.addScalar("qq", new org.hibernate.type.StringType());
	                        query.addScalar("realName", new org.hibernate.type.StringType());
	                        query.addScalar("version", new org.hibernate.type.IntegerType());
	                        List<Object[]> list = query.list();
	                        List<IoLog> logs = new ArrayList<IoLog>();
	                        for (int i = 0; i < list.size(); i++) {
	                            logs.add(createIoLogFromObject(list.get(i), user));
	                        }
	                        return logs;

	                    } else {
	                        String hql = "from IoLog io where io.user.userId = " + user.getUserId() + " and io.status = " + ioStatus;
	                        if (ioType != null && ioType != 0) {
	                            hql = hql + " and io.ioType = " + ioType;
	                        }
	                        if (begin != null) {
	                            hql = hql + " and io.createTime > '" + Utils.NORMAL.format(begin) + "'";
	                        }
	                        if (end != null) {
	                            hql = hql + " and io.createTime < '" + Utils.NORMAL.format(end) + "'";
	                        }

	                        Long sum = (Long) getHibernateTemplate().find("select count(*)" + hql).listIterator().next();
	                        page.setSum(sum);
	                        Long count = page.getCountPage3();
	                        final long from = count < page.getCurPage() ? count : page.getCurPage();
	                        page.setCurPage(from);

	                        hql = hql + " order by io.createTime desc";
	                        Query query = session.createQuery(hql);
	                        query.setFirstResult((int) ((from - 1) * page.getPageSize3()));
	                        query.setMaxResults(page.getPageSize3());

	                        return query.list();
	                    }
	                }
	            });
	        } catch (RuntimeException e) {
	            throw e;
	        }
	        return ioLogs;
	    }
	 
	 private IoLog createIoLogFromObject(Object[] objs, User user) {
	        IoLog log = new IoLog();
	        log.setIoId((Integer) objs[0]);
	        log.setUser(user);
	        log.setIoNo((String) objs[2]);
	        log.setIoType((Integer) objs[3]);
	        log.setMoney((Double) objs[4]);
	        log.setAgo((Double) objs[5]);
	        log.setAfter((Double) objs[6]);
	        log.setCreateTime((Date) objs[7]);
	        log.setStatus((Integer) objs[8]);
	        log.setDetails((String) objs[9]);
	        log.setTbUrl((String) objs[10]);
	        log.setQq((String) objs[11]);
	        log.setRealName((String) objs[12]);
	        log.setVersion((Integer) objs[13]);
	        return log;
	    }
}
